package yang.VirtualMachine.chapter4;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;

import yang.VirtualMachine.chapter4.SoftRef.User;

public class SoftRefQ {
	static ReferenceQueue<User> softQueue = null;
	public static class CheckRefQueue extends Thread {
		@Override
		public void run() {
			while (true) {
				if (softQueue != null) {
					UserSoftReference obj = null;
					try {
						obj = (UserSoftReference) softQueue.remove();//删除并返回，阻塞方法
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (obj != null) {
						System.out.println("user id " + obj.uid + " is delete");
					} else {
						System.out.println("obj为null");
					}
				}
				
			}
		}
	}
	
	/**
	 * 检查的时候知道哪个被记录删除了
	 * @author xinxin
	 */
	public static class UserSoftReference extends SoftReference<User> {
		int uid;
		public UserSoftReference(User referent, ReferenceQueue<? super User> q) {
			super(referent, q);
			uid = referent.id;
		}
	}
	
	

	public static void main(String[] args) throws InterruptedException {
		// 启动检查线程并设置为守护线程（系统无非守护线程后自动结束）
		Thread t = new CheckRefQueue();
		t.setDaemon(true);
		t.start();
		
		// 软引用并将强引用置空
		User u = new User(1, "yangxx");
		softQueue = new ReferenceQueue<>();
		// 当软引用被回收时，其软引用将被加入softQueue
		UserSoftReference userSoftRef = new UserSoftReference(u, softQueue);
		u = null;
		
		System.out.println(userSoftRef.get());
		System.gc();
		// 内存足够， 不会被吸收
		System.out.println("After GC:");
		System.out.println(userSoftRef.get());
		
		System.out.println("try to create byte array and GC");
		byte[] b = new byte[1024*7*948];
		System.gc();
		System.out.println(userSoftRef.get());

		Thread.sleep(1000);
	}

}
